/**
 * @author flashflexpro@gmail.com
 * Date: 10-12-24
 * Time: ����5:35
 */
package com.flashflexpro.flexdirector.crossfingers {
import com.flashflexpro.as3lib.EventDictionary;


import flash.utils.describeType;

import flash.utils.getQualifiedClassName;

import mx.core.UIComponent;

public class CrossFingers {

    /**
     *
     * @param currentCom from which to start
     * @param getter process getter? or only public properties.
     */
    public function process(currentCom:UIComponent, carePackages:Array, resultDic:EventDictionary, previousDesc:ComRefsDesc, previousRef:String, getter:Boolean):ComRefsDesc {
        var currentComDesc:ComRefsDesc = resultDic.get( currentCom.uid );
        if (currentComDesc == null) {
            currentComDesc = new ComRefsDesc();
            currentComDesc.uid = currentCom.uid;
            resultDic.put( currentCom.uid, currentComDesc );
            currentComDesc.previousComs[ previousRef ] = previousDesc;

            var currentComClassName:String = getQualifiedClassName(currentCom);
            var belongsToPackage:Boolean = false;
            for each(var eachCarePackage:String in carePackages) {
                if (currentComClassName.indexOf(eachCarePackage) == 0) {
                    belongsToPackage = true;
                }
            }

            if (belongsToPackage) {
                var nextRefs:Array = getComRefs(currentCom, getter);
                for (var nr:String in nextRefs) {
                    var nc:UIComponent = currentCom[ nr ] as UIComponent;
                    if (nc != null) {
                        currentComDesc.nextComs[ nr ] = process(nc, carePackages, resultDic, currentComDesc, nr, getter);
                    }
                    else {
                        //todo:
                        trace( "todo: ignore none UIComponent:" + currentCom[ nr ] );
                    }
                }
            }
            else{
                //todo:
                trace( "todo: ignore careless ref:" + currentComClassName );
            }

        }
        else {
            for (var nextRef:String in currentComDesc.nextComs) {
                var nextDesc:ComRefsDesc = currentComDesc.nextComs[ nextRef ];
                if (nextDesc != null && resultDic.get( nextDesc.uid ) == null) {
                    process(currentCom[ nextRef ], carePackages, resultDic, currentComDesc, nextRef, getter)
                }
                else{
                    trace( "ignored existing desc:" + nextDesc );
                }
            }
        }
        return currentComDesc;
    }

    private function getComRefs(u:UIComponent, getter:Boolean):Array {

        var rt:Array = [];
        var descXml:XML = describeType(u);
        if (getter) {
            var accList:XMLList = descXml.accessor;
            var attrName:String;
            for each(var acx:XML in accList) {
                attrName = String(acx.@name);
                if (acx.@access == "writeonly") {
                    continue;
                }

                //used but without id
                if (false&&_autoGenNamePattern.test(attrName)) {
                    continue;
                }
                rt.push(attrName);
            }

        }
        var varList:XMLList = descXml.variable;
        for each(var vrx:XML in varList) {
            attrName = vrx.@name as String;

            //used but without id
            if (false&&_autoGenNamePattern.test(attrName)) {
                continue;
            }
            rt.push(attrName);
        }

        return rt;
    }


    private static var _autoGenNamePattern:RegExp = new RegExp("^[_A-Za-z]*\\d$");
}
}
